package com.glzn.springboot03.controller;

import com.glzn.springboot03.config.HttpSessionConfig;
import com.glzn.springboot03.entity.Mqtt;
import com.glzn.springboot03.entity.User;
import com.glzn.springboot03.mqtt.MqttConfig;
import com.glzn.springboot03.mqtt.MqttPublishClient;
import com.glzn.springboot03.service.MqttService;
import com.glzn.springboot03.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * @author Administrator
 */
@Controller
public class LoginController {
	@Autowired
	private UserService userService;

	@Autowired
	MqttConfig mqttConfig;

	@Autowired
	RedisTemplate redisTemplate;

	@Autowired
	MqttService mqttService;

	@GetMapping(value = {"/","/login"})
	public String loginPage(){
		return "login";
	}

	@PostMapping("/login")
	public String main(String login, String password, HttpSession session, Model model){
		User user = null;
		try {
			user = userService.findByLogin(login, password);
			session.setAttribute("user", user);
			return "redirect:/device.html";
		} catch (Exception e) {
			model.addAttribute("LOGIN_ERROR", e.getMessage());
			model.addAttribute("login", login);
			return "login";
		}
	}

	@GetMapping("/wx/login")
	@ResponseBody
	public String wxLogin(String login, String password, HttpSession session, Model model){
		User user = null;
		try {
			user = userService.findByLogin(login, password);
			session.setAttribute("user", user);
			return "ok";
		} catch (Exception e) {
			return e.getMessage();
		}
	}

	@RequestMapping("/device.html")
	public String device(@ModelAttribute("DEVICE_ERROR") String deviceError, ModelMap modelMap) {
		//从数据库中获取device list
		List<Mqtt> mqttList = mqttService.findAll();
		modelMap.put("mqttList", mqttList);
		modelMap.put("DEVICE_ERROR", deviceError);
		return "device";
	}

	@GetMapping("/wx/device")
	@ResponseBody
	public List<Mqtt> wxDeviceList() {
		return mqttService.findAll();
	}

	public boolean isDeviceInUsed(Integer deviceId) {
		ListOperations opsForList = redisTemplate.opsForList();
		for (int i = 0; i < opsForList.size("device_id"); i++) {
			Integer id = (Integer) opsForList.index("device_id", i);
			if (id != null && id.equals(deviceId)) {
				return true;
			}
		}
		return false;
	}

	public boolean isSameDevice(String sessionId, Integer deviceId) {
		Integer s = (Integer) redisTemplate.opsForValue().get(sessionId);
		return deviceId.equals(s);
	}

	@RequestMapping("/main.html")
	public String mainPage(HttpSession session,
	                       @RequestParam(value = "id", required = false) Integer id,
	                       @RequestParam(value = "force", required = false) String force,
	                       RedirectAttributes attributes) {
		//id不为空，说明是device页面跳转过来的
		if (id != null) {
			/**
			 * 有哪些情况是不能进入到main页面的:
			 * 1、选择了设备但是别人正在使用这个设备
			 * 2、如果自己在使用，再次选择必须先删除和原来设备相关的信息
			 */

			//判断id是不是有人已经在使用了，如果已经在使用了，那么就清除之前使用这个id的session
			System.out.println("session id="+session.getId());
			List<HttpSession> sessionList = HttpSessionConfig.getActiveSessions();

			//判断当前的session是否已经存在了
			for (HttpSession httpSession : sessionList) {
				if (httpSession.getId().equals(session.getId())) {
					System.out.println("当前的session已经存在了");
					//TODO 还要判断是否和之前的已经用过的设备id相同
					if (isSameDevice(session.getId(), id)) {
						return "main";
					} else {
						//删除掉原来的device
						session.removeAttribute("mqttPublishClient");
					}
				}
			}
			attributes.addFlashAttribute("DEVICE_ERROR", null);
			//判断设备是否已经再使用了
			if (isDeviceInUsed(id)) {
				if ("false".equals(force)) {
					attributes.addFlashAttribute("DEVICE_ERROR", "有人已经在使用了");
					return "redirect:/device.html";
				} else {
					// 强制下线:删除session，删除缓存
					// 根据id查询seesion id
					for (HttpSession httpSession : sessionList) {
						String sessionId = httpSession.getId();
						// 根据session id查询session
						if (isSameDevice(sessionId, id)) {
							// 删除session
							httpSession.invalidate();
							// 删除缓存
							redisTemplate.opsForList().remove("device_id", 0, id);
						}
					}
				}
			}
			// 如果seesion中已经有了设备，需要先清除原来的id
			Integer oldDeviceId = (Integer) redisTemplate.opsForValue().get(session.getId());
			if (oldDeviceId != null) {
				redisTemplate.opsForList().remove("device_id", 0, oldDeviceId);
			}
			// 将设备id存放到缓存中
			redisTemplate.opsForList().leftPush("device_id", id);
			//将设备id保存到session中
			session.setAttribute("device_id", id);
			// 创建设备类，并保存到session中
			List<MqttPublishClient> clientList = mqttConfig.getPublishClients();
			for (MqttPublishClient mqttPublishClient : clientList) {
				if(mqttPublishClient.getMqtt().getId().equals(id)) {
					session.setAttribute("mqttPublishClient", mqttPublishClient);
				}
			}
			// 保存设备和session的关联
			redisTemplate.opsForValue().set(session.getId(), id);
		}
		//id为空，说明就是首页
		return "main";
	}

	@GetMapping("/wx/main")
	@ResponseBody
	public String mainPage2(HttpSession session,
	                       @RequestParam(value = "id", required = false) Integer id,
	                       @RequestParam(value = "force", required = false) String force) {
		List<HttpSession> sessionList = HttpSessionConfig.getActiveSessions();
		// 当前session是否已经存在了
		for (HttpSession httpSession : sessionList) {
			if (httpSession.getId().equals(session.getId())) {
				System.out.println("当前的session已经存在了");
				//TODO 还要判断是否和之前的已经用过的设备id相同
				if (isSameDevice(session.getId(), id)) {
					return "ok";
				} else {
					//删除掉原来的device
					session.removeAttribute("mqttPublishClient");
				}
			}
		}
		if (isDeviceInUsed(id)) {
			if ("false".equals(force)) {
				return "failed";
			} else {
				// 强制下线:删除session，删除缓存
				// 根据id查询seesion id
				for (HttpSession httpSession : sessionList) {
					String sessionId = httpSession.getId();
					// 根据session id查询session
					if (isSameDevice(sessionId, id)) {
						// 删除session
						httpSession.invalidate();
						// 删除缓存
						redisTemplate.opsForList().remove("device_id", 0, id);
					}
				}
			}
		}
		// 如果seesion中已经有了设备，需要先清除原来的id
		Integer oldDeviceId = (Integer) redisTemplate.opsForValue().get(session.getId());
		if (oldDeviceId != null) {
			redisTemplate.opsForList().remove("device_id", 0, oldDeviceId);
		}
		// 将设备id存放到缓存中
		redisTemplate.opsForList().leftPush("device_id", id);
		// 将设备id保存到session中
		session.setAttribute("device_id", id);
		// 创建设备类，并保存到session中
		List<MqttPublishClient> clientList = mqttConfig.getPublishClients();
		for (MqttPublishClient mqttPublishClient : clientList) {
			if(mqttPublishClient.getMqtt().getId().equals(id)) {
				session.setAttribute("mqttPublishClient", mqttPublishClient);
			}
		}
		// 保存设备和session的关联
		redisTemplate.opsForValue().set(session.getId(), id);

		return "ok";
	}

	@GetMapping("/process.html")
	public String processPage(HttpSession session,Model model) {
		return "process";
	}

	@RequestMapping("/success")
	public String successPage(HttpSession session,Model model) {
		return "success";
	}

	@RequestMapping("/failed")
	public String failedPage(HttpSession session,Model model) {
		return "failed";
	}
}
